<template>
  <div class="note-container">
    <!-- 顶部搜索和操作区域 -->
    <el-card class="search-card" :body-style="{ padding: '20px' }">
      <div class="card-header">
        <div class="left-section">
          <h2 class="section-title">技术文章管理</h2>
          <span class="subtitle">管理您的技术文章</span>
        </div>
        <div class="right-section">
          <el-button type="primary" :icon="Plus" @click="handleAddArticle" class="add-button">添加文章</el-button>
        </div>
      </div>
      <el-form :inline="true" class="search-form">
        <el-form-item label="文章标题:">
          <el-input v-model="searchKeyword" placeholder="请输入文章标题" clearable />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch">搜索</el-button>
          <el-button @click="resetSearch">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <!-- 文章列表展示区域 -->
    <div class="posts-container">
      <el-empty v-if="filteredPosts.length === 0 && !loading" description="暂无技术文章" />
      <div v-if="loading" class="loading">加载中...</div>
      <transition-group v-else name="post-list" tag="div" class="post-grid">
        <el-card 
          v-for="(post, index) in paginatedPosts" 
          :key="post.id" 
          class="post-card"
          :body-style="{ padding: '0' }"
          shadow="hover"
        >
          <div class="post-image-container">
            <el-image 
              :src="post.imgUrl || defaultImageUrl"
              fit="cover"
              class="post-image"
              loading="lazy"
            >
              <template #error>
                <div class="image-error">
                  <el-icon><Picture /></el-icon>
                  <span>图片加载失败</span>
                </div>
              </template>
            </el-image>
            <div class="post-overlay">
              <el-button-group class="action-buttons">
                <el-button type="primary" :icon="Edit" circle @click.stop="handleEdit(post)" />
                <el-popconfirm title="确定删除这篇文章吗？" @confirm="handleDelete(post.id)">
                  <template #reference>
                    <el-button type="danger" :icon="Delete" circle @click.stop />
                  </template>
                </el-popconfirm>
              </el-button-group>
            </div>
          </div>
          <div class="post-content">
            <h3 class="post-title">{{ post.title }}</h3>
            <div class="post-tags">
              <el-tag 
                v-for="(tag, tagIndex) in post.tags" 
                :key="tagIndex"
                :type="tagTypes[tagIndex % tagTypes.length]"
                effect="light"
                size="small"
                class="tag"
              >
                {{ tag }}
              </el-tag>
            </div>
            <div class="post-meta">
              <span><el-icon><Pointer /></el-icon> {{ post.likes }} 点赞</span>
              <span><el-icon><View /></el-icon> {{ post.liulan }} 浏览</span>
            </div>
            <div class="post-footer">
              <span class="post-date">
                <el-icon><Calendar /></el-icon>
                {{ formatTime(post.updated_at) }}
              </span>
            </div>
          </div>
        </el-card>
      </transition-group>
    </div>

    <!-- 分页控件 -->
    <div class="pagination-container" v-if="filteredPosts.length > 0">
      <el-pagination
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :page-sizes="[6, 9, 12, 15]"
        layout="total, sizes, prev, pager, next, jumper"
        :total="totalPosts"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        background
      />
    </div>

    <!-- 添加/编辑文章对话框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="isEdit ? '编辑文章' : '添加文章'"
      width="70%"
      destroy-on-close
      draggable
    >
      <el-form
        ref="postFormRef"
        :model="postForm"
        :rules="postRules"
        label-width="100px"
        class="post-form"
      >
        <el-form-item label="文章标题" prop="title">
          <el-input v-model="postForm.title" placeholder="请输入文章标题" />
        </el-form-item>
        
        <el-form-item label="文章封面" prop="imgUrl">
          <div v-if="!uploadedImageUrl && !postForm.imgUrl" class="upload-container">
            <el-upload
              class="post-uploader"
              :action="uploadUrl" 
              name="image"
              :show-file-list="false"
              :on-success="handleUploadSuccess"
              :before-upload="beforeUpload"
            >
              <el-icon class="uploader-icon"><Plus /></el-icon>
              <div class="upload-text">点击上传封面图片</div>
            </el-upload>
          </div>
          <div v-else class="preview-container">
            <el-image :src="uploadedImageUrl || postForm.imgUrl" class="preview-image" />
            <div class="preview-actions">
              <el-button type="primary" size="small" @click="resetUpload">更换图片</el-button>
            </div>
          </div>
        </el-form-item>
        
        <el-form-item label="文章内容" prop="content">
           <v-md-editor v-model="postForm.content" height="400px"></v-md-editor>
        </el-form-item>

        <el-form-item label="文章标签" prop="tags">
           <el-select
            v-model="postForm.tags"
            multiple
            filterable
            allow-create
            default-first-option
            placeholder="请选择或输入标签"
            style="width: 100%"
          >
             <el-option
              v-for="item in commonTags"
              :key="item"
              :label="item"
              :value="item"
            />
          </el-select>
        </el-form-item>

        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="点赞数">
              <el-input-number v-model="postForm.likes" :min="0" controls-position="right" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
             <el-form-item label="浏览量">
              <el-input-number v-model="postForm.liulan" :min="0" controls-position="right" />
            </el-form-item>
          </el-col>
        </el-row>

      </el-form>
      
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitForm">确认</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue';
import { ElMessage, ElMessageBox, FormInstance, UploadProps } from 'element-plus';
import { Plus, Edit, Delete, Picture, Calendar, Pointer, View } from '@element-plus/icons-vue';
import { addPostSync, deletePostSync, GetPostById, getPosts, updatePost } from '@/api/Note';
import { formatTime } from '@/utils/time';

// 定义文章类型
interface Post {
  id: number;
  title: string;
  content: string;
  imgUrl: string;
  tags: string[];
  likes: number;
  liulan: number;
  created_at?: string; // 添加创建时间字段
  updated_at: string;
}

// 搜索关键词
const searchKeyword = ref('');

// 标签类型
const tagTypes = ['', 'success', 'warning', 'danger', 'info'];
const commonTags = ref(['Vue', 'React', 'TypeScript', 'JavaScript', 'Node.js', 'CSS', 'HTML', '性能优化', '工程化', '源码阅读', '面试']); // 常用标签

// 文章列表数据
const allPosts = ref<Post[]>([]);
const loading = ref(true);
const currentPage = ref(1);
const pageSize = ref(6); // 每页显示6篇文章
const defaultImageUrl = ref('https://via.placeholder.com/300x180.png?text=No+Image'); // 默认图片
const uploadUrl = computed(() => process.env.NODE_ENV === 'production' ? 'https://back.xuxiao888.com/upload' : 'http://localhost:5000/upload');

// 对话框控制
const dialogVisible = ref(false);
const isEdit = ref(false);
const postFormRef = ref<FormInstance>();
const uploadedImageUrl = ref('');

// 文章表单
const postForm = reactive<Omit<Post, 'id' | 'updated_at' | 'created_at'> & { id?: number }> ({
  title: '',
  imgUrl: '',
  content: '',
  tags: [],
  likes: 0,
  liulan: 0,
});

// 表单验证规则
const postRules = {
  title: [
    { required: true, message: '请输入文章标题', trigger: 'blur' },
    { min: 2, max: 100, message: '长度在 2 到 100 个字符', trigger: 'blur' }
  ],
  content: [
    { required: true, message: '请输入文章内容', trigger: 'blur' },
  ],
  tags: [
    { required: true, message: '请至少选择或输入一个标签', trigger: 'change' },
    { type: 'array', min: 1, message: '请至少选择或输入一个标签', trigger: 'change' }
  ]
};

// 计算属性：过滤后的文章列表
const filteredPosts = computed(() => {
  if (!searchKeyword.value) {
    return allPosts.value;
  }
  return allPosts.value.filter(post => 
    post.title.toLowerCase().includes(searchKeyword.value.toLowerCase())
  );
});

// 计算属性：总文章数
const totalPosts = computed(() => filteredPosts.value.length);

// 计算属性：当前页显示的文章
const paginatedPosts = computed(() => {
  const start = (currentPage.value - 1) * pageSize.value;
  const end = start + pageSize.value;
  return filteredPosts.value.slice(start, end);
});

// 获取所有文章
const fetchPosts = async () => {
  loading.value = true;
  try {
    // 假设 getPosts(0, 9999) 获取所有文章，如果API不支持，需要调整
    const res = await getPosts(0, 9999); 
    if (res.status === 0 && res.data && Array.isArray(res.data.data)) {
      allPosts.value = res.data.data.sort((a, b) => new Date(b.updated_at).getTime() - new Date(a.updated_at).getTime()); // 按更新时间降序
    } else {
      ElMessage.error('获取文章列表失败');
      allPosts.value = [];
    }
  } catch (error) {
    console.error('获取文章列表失败:', error);
    ElMessage.error('获取文章列表失败');
    allPosts.value = [];
  } finally {
    loading.value = false;
  }
};

// 搜索处理
const handleSearch = () => {
  currentPage.value = 1; // 搜索后回到第一页
};

// 重置搜索
const resetSearch = () => {
  searchKeyword.value = '';
  currentPage.value = 1;
};

// 分页处理
const handleSizeChange = (val: number) => {
  pageSize.value = val;
  currentPage.value = 1; // 切换每页数量后回到第一页
};

const handleCurrentChange = (val: number) => {
  currentPage.value = val;
};

// 重置表单
const resetForm = () => {
  Object.assign(postForm, {
    id: undefined,
    title: '',
    imgUrl: '',
    content: '',
    tags: [],
    likes: 0,
    liulan: 0,
  });
  uploadedImageUrl.value = '';
  postFormRef.value?.clearValidate(); // 清除校验状态
};

// 添加文章
const handleAddArticle = () => {
  isEdit.value = false;
  resetForm();
  dialogVisible.value = true;
};

// 编辑文章
const handleEdit = async (post: Post) => {
  isEdit.value = true;
  resetForm();
  // 深拷贝一份数据到表单，防止直接修改列表数据
  Object.assign(postForm, JSON.parse(JSON.stringify(post)));
  // 如果API返回的tags是字符串，需要转换成数组
  if (typeof postForm.tags === 'string') {
      try {
          postForm.tags = JSON.parse(postForm.tags);
      } catch (e) {
          // 如果解析失败，尝试按逗号分割
          postForm.tags = (postForm.tags as string).split(',').map(tag => tag.trim()).filter(Boolean);
      }
  }
  // 确保 tags 是数组
  if (!Array.isArray(postForm.tags)) {
      postForm.tags = [];
  }
  uploadedImageUrl.value = ''; // 编辑时不直接显示上传组件的预览
  dialogVisible.value = true;
};

// 删除文章
const handleDelete = async (id: number) => {
  try {
    const res = await deletePostSync(id);
    if (res.status === 0) {
      ElMessage.success('删除成功');
      fetchPosts(); // 重新获取列表
    } else {
      ElMessage.error(res.message || '删除失败');
    }
  } catch (error) {
    console.error('删除文章失败:', error);
    ElMessage.error('删除失败');
  }
};

// 上传前验证
const beforeUpload: UploadProps['beforeUpload'] = (rawFile) => {
  const isImage = rawFile.type.startsWith('image/');
  const isLt5M = rawFile.size / 1024 / 1024 < 5; // 限制 5MB

  if (!isImage) {
    ElMessage.error('只能上传图片文件!');
    return false;
  }
  if (!isLt5M) {
    ElMessage.error('图片大小不能超过 5MB!');
    return false;
  }
  return true;
};

// 上传成功回调
const handleUploadSuccess: UploadProps['onSuccess'] = (response, uploadFile) => {
  if (response && response.imageUrl) {
    postForm.imgUrl = response.imageUrl; // 更新表单中的图片URL
    uploadedImageUrl.value = URL.createObjectURL(uploadFile.raw!); // 用于本地预览
    ElMessage.success('上传成功');
  } else {
    ElMessage.error(response.message || '上传失败');
  }
};

// 重置上传状态
const resetUpload = () => {
  postForm.imgUrl = '';
  uploadedImageUrl.value = '';
};

// 提交表单
const submitForm = async () => {
  if (!postFormRef.value) return;
  
  await postFormRef.value.validate(async (valid) => {
    if (valid) {
      loading.value = true; // 开始加载状态
      try {
        let res;
        // 确保 tags 是字符串数组
        const payload = {
            ...postForm,
            tags: Array.isArray(postForm.tags) ? postForm.tags : [],
        };

        if (isEdit.value && postForm.id) {
          // 编辑文章
          res = await updatePost(postForm.id, payload);
        } else {
          // 添加文章
          const { id, ...addData } = payload; // 移除可能存在的id
          res = await addPostSync(addData);
        }

        if (res.status === 0) {
          ElMessage.success(isEdit.value ? '更新成功' : '添加成功');
          dialogVisible.value = false;
          fetchPosts(); // 重新获取列表
        } else {
          ElMessage.error(res.message || (isEdit.value ? '更新失败' : '添加失败'));
        }
      } catch (error) {
        console.error('保存失败:', error);
        ElMessage.error('操作失败');
      } finally {
         loading.value = false; // 结束加载状态
      }
    } else {
      console.log('表单验证失败!');
      return false;
    }
  });
};

// 生命周期钩子
onMounted(() => {
  fetchPosts();
});
</script>

<style scoped lang="scss">
.note-container {
  padding: 20px;
  
  .search-card {
    margin-bottom: 20px;
    border-radius: 8px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
    
    .card-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 20px;
      
      .left-section {
        .section-title {
          margin: 0;
          font-size: 22px;
          font-weight: 600;
          color: #303133;
        }
        
        .subtitle {
          font-size: 14px;
          color: #909399;
          margin-top: 4px;
          display: block;
        }
      }
      
      .add-button {
        padding: 10px 20px;
        font-weight: 500;
      }
    }
    
    .search-form {
      display: flex;
      flex-wrap: wrap;
      gap: 10px;
    }
  }
  
  .posts-container {
    min-height: 400px; // 避免加载时页面跳动
    .loading {
      text-align: center;
      padding: 50px;
      color: #909399;
    }
  }
  
  .post-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); // 响应式网格
    gap: 20px;
    margin-bottom: 30px;
  }
  
  .post-card {
    border-radius: 12px;
    overflow: hidden;
    transition: all 0.3s ease;
    height: 100%;
    display: flex;
    flex-direction: column;
    
    &:hover {
      transform: translateY(-5px);
      box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
      
      .post-overlay {
        opacity: 1;
      }
    }
    
    .post-image-container {
      position: relative;
      height: 180px;
      overflow: hidden;
      background-color: #f5f7fa; // 图片加载时背景色
      
      .post-image {
        width: 100%;
        height: 100%;
        object-fit: cover;
        transition: transform 0.5s ease;
      }
      
      .image-error {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        height: 100%;
        color: #909399;
        
        .el-icon {
          font-size: 32px;
          margin-bottom: 8px;
        }
      }
      
      .post-overlay {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-color: rgba(0, 0, 0, 0.5);
        display: flex;
        justify-content: center;
        align-items: center;
        opacity: 0;
        transition: opacity 0.3s ease;
        
        .action-buttons {
          display: flex;
          gap: 10px;
        }
      }
    }
    
    .post-content {
      padding: 16px;
      flex: 1;
      display: flex;
      flex-direction: column;
      
      .post-title {
        margin: 0 0 10px;
        font-size: 18px;
        font-weight: 600;
        color: #303133;
        line-height: 1.4;
        // 最多显示两行
        overflow: hidden;
        text-overflow: ellipsis;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
      }
      
      .post-tags {
        display: flex;
        flex-wrap: wrap;
        gap: 6px;
        margin-bottom: 12px;
        min-height: 24px; // 避免没标签时跳动
        
        .tag {
          border-radius: 4px;
        }
      }
      
      .post-meta {
        display: flex;
        gap: 15px;
        font-size: 13px;
        color: #606266;
        margin-bottom: 12px;
        align-items: center;
        .el-icon {
          margin-right: 3px;
          vertical-align: middle;
        }
        span {
          display: inline-flex;
          align-items: center;
        }
      }
      
      .post-footer {
        margin-top: auto; // 将日期推到底部
        font-size: 13px;
        color: #909399;
        
        .post-date {
          display: flex;
          align-items: center;
          gap: 4px;
        }
      }
    }
  }
  
  .pagination-container {
    display: flex;
    justify-content: center;
    margin-top: 20px;
  }
  
  // 表单样式
  .post-form {
    .upload-container, .preview-container {
      width: 100%;
      
      .post-uploader {
        border: 1px dashed var(--el-border-color);
        border-radius: 6px;
        cursor: pointer;
        position: relative;
        overflow: hidden;
        width: 250px; // 调整上传框大小
        height: 150px;
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        transition: border-color 0.3s;
        background-color: #fafafa;
        
        &:hover {
          border-color: var(--el-color-primary);
        }
        
        .uploader-icon {
          font-size: 28px;
          color: #8c939d;
          margin-bottom: 8px;
        }
        
        .upload-text {
          color: #8c939d;
          font-size: 14px;
        }
      }
      
      .preview-image {
        width: 250px;
        height: 150px;
        object-fit: cover;
        border-radius: 6px;
        border: 1px solid #eee;
      }
      
      .preview-actions {
        margin-top: 10px;
      }
    }
  }
  
  // 动画效果
  .post-list-enter-active,
  .post-list-leave-active {
    transition: all 0.5s ease;
  }
  
  .post-list-enter-from,
  .post-list-leave-to {
    opacity: 0;
    transform: translateY(30px);
  }
  
  .post-list-move {
    transition: transform 0.5s ease;
  }
}

// 深度选择器修改 el-dialog 样式
:deep(.el-dialog__body) {
  padding-top: 10px; 
  padding-bottom: 10px;
}

:deep(.el-dialog__footer) {
  padding-top: 10px;
  padding-bottom: 20px;
}

:deep(.el-form-item) {
  margin-bottom: 22px; // 统一表单项间距
}

:deep(.v-md-editor) {
  box-shadow: none; // 去除编辑器默认阴影
  border: 1px solid #dcdfe6;
}
</style>
